﻿#include "FFmpegAudioCapturer.h"

#include "../common/thread_pool.h"
#ifndef WIN32
#include <malloc.h>
#endif
FFmpegAudioSource::FFmpegAudioSource(const std::string& uri, const std::map<std::string, std::string>& opts)
	:m_audioourl(uri)
{
	
	stopThread.store(true);
}

FFmpegAudioSource::~FFmpegAudioSource()
{
	SPDLOG_LOGGER_ERROR(spdlogptr, "stop start ");


	stopThread.store(true);
	std::this_thread::sleep_for(std::chrono::milliseconds(10));

	m_pSource->SyncStop();
	MediaSourceAPI::deleteMediaSource(m_pSource);
	if (m_audioDecder !=nullptr)
	{
		delete  m_audioDecder;
		m_audioDecder = nullptr;
	}
	if (m_resampler != nullptr)
	{
		delete  m_resampler;
		m_resampler = nullptr;
	}
#ifndef WIN32
	// 释放一些内存回给系统
	malloc_trim(0);
#endif

	SPDLOG_LOGGER_ERROR(spdlogptr, "stop end ");


}

int FFmpegAudioSource::Init(int nSampleRate, int nChannel, int nBitsPerSample)
{
	return 0;
}

int FFmpegAudioSource::Init(const std::map<std::string, std::string>& opts)
{
	return 0;
}

int FFmpegAudioSource::Start()
{
	SPDLOG_LOGGER_INFO(spdlogptr, "Start ");
	if (stopThread.load() == true)
	{	

		stopThread.store(false);
		m_pSource = MediaSourceAPI::CreateMediaSource(m_audioourl, this, false, true);
		m_pSource->Run(false);
		return true;
	}
	else
	{
		return false;
	}


}

void FFmpegAudioSource::Stop()
{
}

void FFmpegAudioSource::Destroy()
{

}

void FFmpegAudioSource::RegisterPcmCallback(PcmCallBack pcmCallback)
{
	m_pcmCallback = pcmCallback;
}

void FFmpegAudioSource::RegisterAacCallback(AacCallBack aacCallBack)
{
	
}

void FFmpegAudioSource::OnSourceConnected(void* arg, const std::map<std::string, std::string>& opts)
{
	SPDLOG_LOGGER_INFO(spdlogptr, "OnSourceConnected ");
	auto streamInfo = opts;
	auto  fmat = atoi(streamInfo["format"].c_str());
	auto  sample_rate = atoi(streamInfo["sample_rate"].c_str());
	auto  nb_channels = atoi(streamInfo["nb_channels"].c_str());
	auto  audiocodecname = streamInfo["audiocodecname"].c_str();
	auto  bit_rate = atoi(streamInfo["bit_rate"].c_str());

	auto  frame_size = atoi(streamInfo["frame_size"].c_str());
	m_resampler = AudioResamplerAPI::CreateAudioResampler(
		(AUDIOMIX_AVSampleFormat)fmat, sample_rate, nb_channels,
		(AUDIOMIX_AVSampleFormat)AUDIOMIX_AVSampleFormat::AUDIOMIX_FMT_S16, m_sample_rate, m_nb_channels);
	if (frame_size<1000)
	{
		frame_size = 1152;
	}
	m_resampler->SetOutFramesize(frame_size);

	m_audioDecder = FFmpegAudioDecoderAPI::CreateDecoder(streamInfo);

	// 处理音频数据的线程函数
	netlib::ThreadPool::getInstance().append([&]()
		{		
		
			while (!stopThread) 
			{			
				int sample_size = 0;
				uint8_t* output_data[AV_NUM_DATA_POINTERS] = { 0 };
				int ret = m_resampler->GetOneFrame(output_data, &sample_size);
				if (ret < 0)
				{
				//	std::unique_lock<std::mutex> lock(m_mutex);
					//audioDataCV.wait(lock, [&]() { return  !stopThread.load(); });
					if (stopThread.load())
					{
						return;
					}
					for (int i = 0; i < AV_NUM_DATA_POINTERS; ++i)
					{
						if (output_data[i] != nullptr) {
							delete[] output_data[i];
							output_data[i] = nullptr;
						}
					}
					std::this_thread::sleep_for(std::chrono::milliseconds(5));
					continue;
				}
				m_pcmCallback(output_data[0], sample_size, m_sample_rate, m_nb_channels, 0);
				for (int i = 0; i < AV_NUM_DATA_POINTERS; ++i) {
					if (output_data[i] != nullptr) {
						delete[] output_data[i];
						output_data[i] = nullptr;
					}
				}
				continue;
			}
		});
}

void FFmpegAudioSource::OnSourceDisConnected(int err)
{



}

void FFmpegAudioSource::OnSourceAudioPacket(const char* id, AVPacket* packet)
{
	



}

void FFmpegAudioSource::OnSourceVideoPacket(const char* id, uint8_t* aBytes, int aSize, int64_t ts,bool bKey)
{

	

}

void FFmpegAudioSource::OnSourceAudioPacket(const char* id, uint8_t* aBytes, int aSize, int64_t t)
{

	std::unique_lock<std::mutex> lock(m_mutex);
	int outSize = 0;

	int nb_samples = 0;
	uint8_t* outData[AV_NUM_DATA_POINTERS] = { 0 };
	m_audioDecder->DecodeData(aBytes, aSize, outData, &outSize, &nb_samples);
	if (outSize>0)
	{
		auto res = m_resampler->FillingPCM(outData, outSize, nb_samples);
	}


	return;
	//audioDataCV.notify_one();
}
